<template>
	<view class="charge-wrapper">
		<scroll-view scroll-y="true" class="recharge-popup">
			<!-- 标题 -->
			<view class="pay-tip-txt">感谢您支持作者，解锁后可继续观看</view>

			<!-- 视频信息 -->
			<view class="video-name">
				<view class="txt" v-if="videoName">{{
					`${videoName} · 第${currentSort}集`
				}}</view>
				<view class="txt" v-else>{{ `第${currentSort}集` }}</view>

				<button
					slot="value"
					open-type="im"
					:data-im-id="imId"
					class="im-btn"
					@im="ImBtnCallback"
					@error="ImBtnError"
				>
					<u-icon
						name="kefu-ermai"
						color="#666666"
						:style="{
							marginRight: '4px',
							fontSize: '18px',
						}"
					></u-icon>
					<text
						:style="{
							fontSize: '15px',
							color: '#666666',
						}"
						>联系客服</text
					>
				</button>
			</view>

			<!-- 剩余钻石 -->
			<view class="balance-wrapper">
				<view class="balance">
					<text
						>余额: {{ balance }}钻石
						<text v-if="give_balance !== 0"
							>（含赠送{{ give_balance }}钻石）</text
						></text
					>
				</view>

				<view class="gold-pay-info" v-if="one_price && one_price !== 0">
					<text>解锁本集：{{ one_price }}金币</text>
				</view>
			</view>

			<!-- 支付模板列表 -->
			<view class="pay-template-warpper" v-if="!IsUseAdPay">
				<view
					class="template-item"
					v-for="(item, index) of payTemplateList"
					:key="item.id"
					@click="selectItem(item)"
				>
					<view
						:class="
							item.pay_type === 1 && item.pay_day == 365
								? 'template-tag hj'
								: 'template-tag'
						"
						v-if="item.corner_text"
						>{{ item.corner_text }}</view
					>
					<image
						class="template-bg"
						v-if="item.corner_text"
						:src="
							OSSImgUrl(
								`${
									item.pay_type === 1 && item.pay_day == 365
										? 'pay-template-bg-hj.png'
										: 'pay-template-bg.png'
								}`
							)
						"
					></image>
					<image
						mode="aspectFit"
						class="template-bg-type"
						v-if="item.corner_text"
						:src="
							OSSImgUrl(
								`${
									item.pay_type === 1 && item.pay_day == 365
										? 'pay-template-bg-type-hj.png'
										: 'pay-template-bg-type' + item.pay_type + '.png'
								}`
							)
						"
					></image>
					<view
						class="template-content"
						:style="{
							borderRadius: item.is_default === 1 ? '7px' : 'unset',
							backgroundColor: item.is_default === 1 ? '#fff' : 'unset',
						}"
					>
						<view class="pay-money">{{ item.text_pay }}</view>
						<view class="pay-gold">
							<image
								style="height: 48rpx"
								mode="widthFix"
								:src="
									OSSImgUrl(
										`${
											item.pay_type === 1 && item.pay_day == 365
												? 'vip-icon.png'
												: 'gold-icon.png'
										}`
									)
								"
							/>
							<view class="gold-content">{{ item.text_get }}</view>
						</view>
						<view
							class="pay-give"
							:style="{
								color: item.is_default === 1 ? '#FD6F09' : '#fff',
							}"
							>{{ item.text_gift }}</view
						>
					</view>
				</view>
			</view>

			<!-- 广告解锁选项 -->
			<view class="ad-section" v-if="IsUseAdPay">
				<view class="section-title">广告解锁</view>
				<view class="ad-desc">
					<text>观看一段广告即可解锁本集内容</text>
					<text>制作不易，感谢您的支持</text>
				</view>

				<button class="ad-btn" @click="adThis">观看广告解锁本集</button>
			</view>

			<!-- 充值说明 -->
			<view class="agreement">
				<view>充值说明：</view>
				<block v-for="item of describeList">
					<view v-if="typeof item === 'string'">{{ item }}</view>
					<block v-else>
						<block v-for="child of item">
							<text
								v-if="child.includes('《')"
								class="link"
								@click="goToOtherPage('pay')"
								>{{ child }}</text
							>
							<block v-else>
								{{ child }}
							</block>
						</block>
					</block>
				</block>
			</view>
		</scroll-view>
		<u-toast ref="uToast"></u-toast>
	</view>
</template>

<script>
import {
	getApiPayTemplate,
	getApiPayParams,
	getOrderStatus,
} from '@/api/payTemplate'
import { getPayDescribe } from '@/api/teleplay'
import { OSSImgUrl, updateUserInfo } from '@/utils'
import { showMessage } from '@/utils/message'
import Decimal from 'decimal.js'
import store from '@/store/index'

const { getPlayletManager } = tt

export default {
	props: {},
	data() {
		return {
			pm: null,
			title: 'Hello Charge',
			videoName: '', // 从缓存获取，不通过props传递
			currentSort: 1, // 从缓存获取，不通过props传递
			videoId: 0, // 视频ID，从缓存获取
			payTemplateList: [], // 支付模板列表
			selectedIndex: 0, // 当前选中的支付模板索引
			IsUseAdPay: store.state.global.IsHasChannelType, // 是否使用广告解锁
			balance: 0, // 钻石余额
			give_balance: 0, // 赠送余额
			one_price: 0, // 单集价格
			describeList: [], // 充值说明
			imId: store.state.global.ImId, // 客服ID
			combi_id: 0, // 充值模版组合id
			template_id: 0, // 充值模版id
			timer: null, // 定时器
			count: 0, // 记录请求次数
			flag: true, // 节流阀
		}
	},
	async beforeCreate() {
		const pm = await getPlayletManager({
			is: 'charge', // 和插槽同名
		})
		this.pm = pm
		console.error(pm, this, 'charge_pm_this_beforeCreate')
	},
	async created() {
		console.log('chargeCreated')
		this.IsUseAdPay = store.state.global.IsHasChannelType

		// 从缓存中获取解锁参数
		try {
			// 优先从解锁时缓存的数据获取信息
			const unlockInfo = uni.getStorageSync('unlockInfo')
			if (unlockInfo) {
				console.log('从unlockInfo缓存获取到数据:', unlockInfo)

				if (unlockInfo.seq) {
					this.currentSort = unlockInfo.seq
					console.log('从unlockInfo获取到当前集数:', this.currentSort)
				}
			} else {
				console.log('缓存中没有找到unlockInfo')
			}
		} catch (error) {
			console.error('获取unlockInfo缓存失败:', error)
		}

		// 从缓存中获取视频信息
		try {
			// 从本地存储获取剧集信息
			const episodeInfo = uni.getStorageSync('episodeInfo')
			if (episodeInfo) {
				if (episodeInfo.video_name) {
					this.videoName = episodeInfo.video_name
					console.log('从缓存获取到视频名称:', this.videoName)
				}

				if (episodeInfo.sort) {
					this.currentSort = episodeInfo.sort
					console.log('从缓存获取到当前集数:', this.currentSort)
				}
			} else {
				console.log('缓存中没有找到剧集信息')
			}
		} catch (error) {
			console.error('获取缓存剧集信息失败:', error)
		}

		// 获取充值说明
		try {
			const res = await getPayDescribe({
				eid: uni.getStorageSync('userInfo').eid,
			})
			if (res.code === 200) {
				this.describeList = res.data.map((item) => {
					const pattern = /《.*?》/
					if (pattern.test(item)) {
						return this.formatText(item)
					}
					return item
				})
			}
		} catch (error) {
			console.error('获取充值说明失败', error)
		}

		// 获取支付模板
		this.getPayTemplate()
	},
	beforeMount() {
		console.log('chargeBeforeMount')
	},
	mounted() {
		console.log('chargeMounted')
	},
	beforeUpdate() {
		console.log('chargeBeforeUpdate')
	},
	updated() {
		console.log('chargeUpdated')
	},
	beforeDestroy() {
		console.log('chargeBeforeDestroy')
	},
	destroyed() {
		console.log('chargeDestroyed')
	},
	methods: {
		OSSImgUrl,
		// 获取支付模板
		async getPayTemplate() {
			let userInfo = uni.getStorageSync('userInfo')
			// 如果获取到的是Json字符串就转换数据
			typeof userInfo === 'object'
				? userInfo
				: (userInfo = JSON.parse(userInfo))
			const eid = userInfo.eid

			// 先使用内部存储的videoId
			let videoId = this.videoId

			// 如果内部没有，再从缓存获取剧集信息
			if (!videoId) {
				// 先从解锁缓存获取
				const unlockInfo = uni.getStorageSync('unlockInfo')
				if (unlockInfo) {
					// 注意：不应该直接使用unlockInfo.albumId作为videoId
					// 应该优先获取episodeInfo中的video_id
					console.log('从缓存获取到unlockInfo:', unlockInfo)
				}

				// 从episodeInfo缓存获取
				const episodeInfo = uni.getStorageSync('episodeInfo')
				if (episodeInfo) {
					videoId = Number(episodeInfo.video_id) || 0
					console.log('从episodeInfo获取videoId:', videoId)

					// 更新内部存储的videoId
					this.videoId = videoId

					// 如果还没有设置currentSort，则从episodeInfo获取
					if (!this.currentSort && episodeInfo.sort) {
						this.currentSort = episodeInfo.sort
						console.log('从episodeInfo获取currentSort:', this.currentSort)
					}

					// 如果还没有设置videoName，则从episodeInfo获取
					if (!this.videoName && episodeInfo.video_name) {
						this.videoName = episodeInfo.video_name
						console.log('从episodeInfo获取videoName:', this.videoName)
					}
				}
			}

			console.log('支付参数:', {
				videoId,
				currentSort: this.currentSort,
				videoName: this.videoName,
			})

			if (!eid || !videoId) {
				console.error('缺少必要的参数eid或videoId')
				return
			}

			try {
				const { data } = await getApiPayTemplate(eid, videoId, this.currentSort)

				this.combi_id = data.combi_id
				this.template_id = data.template_id
				this.one_price = data.one_price
				this.payTemplateList = data.list || []

				console.log('支付模板:', this.payTemplateList)

				// 获取用户余额
				const { balance, give_balance } = uni.getStorageSync('balance')
				// 如果没有获取到余额就为0
				const balanceNum = balance ? balance : 0
				const giveNum = give_balance ? give_balance : 0
				this.balance = balanceNum + giveNum
				this.give_balance = giveNum
			} catch (error) {
				console.error('获取支付模板失败', error)
			}
		},

		// 选择支付模板
		async selectItem(item) {
			if (this.flag) {
				const { pay_type, id, pay_money } = item

				// 修改选中状态
				this.payTemplateList.forEach((item) => {
					// 如果id相同则为当前选中项
					if (item.id === id) {
						item.is_default = 1
					} else {
						item.is_default = 0
					}
				})

				this.flag = false
				const eid = uni.getStorageSync('userInfo').eid

				// 从store获取aid和channel_id
				const aid = store.state.user.defaultParams.aid
				const channel_id = store.state.user.defaultParams.channel_id

				// 优先使用内部存储的videoId
				let videoId = this.videoId

				// 如果内部没有videoId，尝试从缓存获取
				if (!videoId) {
					// 应该从episodeInfo中获取video_id作为videoId
					const episodeInfo = uni.getStorageSync('episodeInfo')
					if (episodeInfo && episodeInfo.video_id) {
						videoId = Number(episodeInfo.video_id)
						this.videoId = videoId
						console.log('从episodeInfo获取videoId:', videoId)
					}
				}

				console.log('支付参数:', {
					videoId,
					currentSort: this.currentSort,
					aid,
					channel_id,
				})

				if (!videoId) {
					console.error('无法获取视频ID')
					this.flag = true
					return
				}

				// 获取支付的必要参数
				try {
					const res = await getApiPayParams({
						eid,
						order_type: pay_type,
						pay_money,
						channel_id,
						aid,
						oid_package: id,
						oid_template: this.template_id,
						oid_combi: this.combi_id,
						product_id: videoId,
						sort: this.currentSort,
					})

					console.log('支付参数:', res)

					if (res.data.type === 1) {
						// 钻石
						uni.showLoading({
							title: '支付请求中...',
							mask: true,
						})

						const thmeData = res.data

						tt.requestOrder({
							data: res.data.data,
							byteAuthorization: res.data.byteAuthorization,
							success: (res) => {
								console.log('下单成功:', res)

								tt.getOrderPayment({
									orderId: res.orderId,
									success: (res) => {
										uni.hideLoading()
										console.log('收银台拉起成功:', res)

										this.timer = setInterval(async () => {
											// 定时执行任务，检查订单状态
											this.handleTimeOut(
												this.timer,
												eid,
												thmeData.order_id,
												async () => {
													// 支付成功更新用户信息
													await updateUserInfo()
													// 支付成功回调
													this.paySuccess()
													showMessage('充值成功')
												}
											)
										}, 1000)
									},
									fail: (err) => {
										console.log('收银台拉起失败:', err)
										if (err.errNo == 9) {
											this.timer = setInterval(async () => {
												// 定时执行任务
												this.handleTimeOut(
													this.timer,
													eid,
													thmeData.order_id,
													async () => {
														// 支付成功更新用户信息
														await updateUserInfo()
														// 支付成功回调
														this.paySuccess()
														showMessage('充值成功')
													}
												)
											}, 1000)
										}
										uni.hideLoading()
									},
								})
							},
							fail: (res) => {
								console.log('下单失败:', res)
								uni.hideLoading()
							},
						})
					} else {
						// jsAPI
						const data = res.data

						uni.showLoading({
							title: '支付请求中...',
							mask: true,
						})

						// 调起抖音支付
						uni.requestPayment({
							provider: 'toutiao',
							service: 5,
							orderInfo: {
								order_id: data.dy_order_id,
								order_token: data.dy_order_token,
							},
							success: async (res) => {
								// code为0支付成功
								if (res.code === 0) {
									uni.showLoading({
										title: '加载中',
										mask: true,
									})
									// 开启定时器
									this.timer = setInterval(async () => {
										// 定时执行任务
										this.handleTimeOut(
											this.timer,
											eid,
											data.order_id,
											async () => {
												// 支付成功更新用户信息
												await updateUserInfo()
												// 支付成功回调
												this.paySuccess()
												showMessage('充值成功')
											}
										)
									}, 1000)
								}
								// 关闭Loading加载提示
								uni.hideLoading()
							},
							fail: (e) => {
								uni.hideLoading()
							},
						})
					}
				} catch (error) {
					console.error('支付失败', error)
				}

				setTimeout(() => {
					this.flag = true
				}, 1000)
			}
		},

		// 处理定时器检查订单状态
		async handleTimeOut(timer, eid, order_id, callback) {
			// 如果请求次数大于5次就取消定时器
			if (this.count >= 5) {
				clearInterval(timer)
				this.count = 0
				uni.hideLoading()
				return
			}

			// 获取订单状态
			const { data } = await getOrderStatus({
				eid,
				order_id,
			})

			// 如果订单状态为1表示支付成功
			if (data === 1) {
				// 关闭定时器
				clearInterval(timer)
				this.count = 0
				uni.hideLoading()
				if (callback) {
					callback()
				}
			} else {
				// 增加请求次数
				this.count++
			}
		},

		// 格式化文本内容（用于处理《服务协议》等链接文本）
		formatText(text) {
			// 正则表达式匹配《xxx》
			const regex = /《(.*?)》/g
			let match
			let lastIndex = 0
			const resultArray = []

			// 使用 exec 方法找到所有匹配项
			while ((match = regex.exec(text)) !== null) {
				// 添加匹配项之前的文本（如果有的话）
				const beforeMatch = text.slice(lastIndex, match.index).trim()
				if (beforeMatch !== '') {
					resultArray.push(beforeMatch)
				}

				// 添加匹配项本身（即《xxx》）
				resultArray.push(match[0])

				// 更新 lastIndex 以指向下一个要处理的文本部分的起始位置
				lastIndex = regex.lastIndex
			}

			// 添加最后一个匹配项之后的文本（如果有的话），包括标点符号
			const afterLastMatch = text.slice(lastIndex).trim()
			if (afterLastMatch !== '') {
				resultArray.push(afterLastMatch)
			}

			// 输出结果数组
			return resultArray
		},

		// 客服按钮回调
		ImBtnCallback(e) {
			console.log('跳转IM客服成功', e.detail)
		},

		// 客服按钮错误
		ImBtnError(e) {
			console.log('拉起IM客服失败', e.detail)
		},

		// 支付解锁当前集
		payThis: function (e) {
			// 原方法保留以兼容旧代码
			console.log('已弃用的支付方法，请使用selectItem')
		},

		// 广告解锁当前集
		adThis: function (e) {
			console.log('广告解锁当前集', e)

			// 调用父组件的广告点击方法
			if (this.$parent && typeof this.$parent.handleAdClick === 'function') {
				this.$parent.handleAdClick()
			} else {
				this.pm.toggleCustomDialog()

				uni.showToast({
					title: '广告功能暂未开放',
					icon: 'none',
				})
			}
		},

		// 支付成功回调
		paySuccess: function () {
			// 再次从缓存中获取最新的剧集信息
			try {
				const episodeInfo = uni.getStorageSync('episodeInfo')
				if (episodeInfo && episodeInfo.video_name && !this.videoName) {
					this.videoName = episodeInfo.video_name
					console.log('支付成功后从缓存更新videoName:', this.videoName)
				}
			} catch (error) {
				console.error('支付成功后获取缓存信息失败:', error)
			}

			// 支付成功后解锁
			this.pm.setCurrentUnlock()

			// 通知父组件支付成功
			if (this.$parent && typeof this.$parent.paySuccess === 'function') {
				this.$parent.paySuccess()
			}
		},

		// 页面跳转
		goToOtherPage(page) {
			switch (page) {
				case 'pay':
					uni.navigateTo({
						url: '/pages/user-agreement/index?type=pay',
					})
					break
				default:
					break
			}
		},
	},
}
</script>

<style>
.charge-wrapper {
	position: relative;
	background: #fff;
	max-height: 900rpx;
	overflow-y: auto;
}

.recharge-popup {
	position: relative;
	background: linear-gradient(to bottom, #ffe6d3 10%, #fff 40%);
	height: 78vh;
	padding: 36rpx 30rpx 0rpx;
	box-sizing: border-box;
}

.pay-tip-txt {
	font-size: 34rpx;
	font-weight: 700;
}

.video-name {
	margin-top: 30rpx;
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.video-name .txt {
	font-size: 32rpx;
	color: #7e7d76;
}

.im-btn {
	flex: 0 0 auto !important;
	display: inline-flex !important;
	align-items: center !important;
	width: auto !important;
	min-width: 0 !important;
	padding: 0 !important;
	background: none !important;
	line-height: normal !important;
	margin: 0;
}

.im-btn::after {
	border: none !important;
}

.balance-wrapper {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-top: 30rpx;
}

.balance {
	font-size: 32rpx;
	color: #fd6f09;
}

.gold-pay-info {
	font-size: 32rpx;
	color: #fd6f09;
}

.pay-options {
	margin-top: 20rpx;
}

.pay-template-warpper {
	margin-top: 70rpx;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}

.template-item {
	position: relative;
	width: 48%;
	height: 190rpx;
	box-sizing: border-box;
	padding: 5px;
	background-color: #f8f8f8;
	border-radius: 7px;
}

.template-item:nth-child(n + 3) {
	margin-top: 70rpx;
}

.template-tag {
	position: absolute;
	top: 0;
	left: 0;
	transform: translate(0px, -45%);
	z-index: 30;

	box-sizing: border-box;
	padding: 12rpx 20rpx;
	font-size: 28rpx;
	color: #fff;
	border-radius: 14px 0 14px 0;
	background: linear-gradient(to bottom, #ffc9a0 10%, #ff6a00 90%);
}

.template-tag.hj {
	background: #000;
}

.template-bg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.template-bg-type {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.template-content {
	position: relative;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.pay-money {
	font-size: 32rpx;
	font-weight: 600;
}

.pay-gold {
	margin-top: 10rpx;
	display: flex;
	align-items: center;
}

.pay-gold .gold-content {
	font-size: 28rpx;
	color: #393939;
	margin-right: 10rpx;
}

.pay-gold image {
	width: 44rpx;
}

.pay-give {
	margin-top: 10rpx;
	font-size: 22rpx;
	color: #fff;
}

.section-title {
	font-size: 30rpx;
	font-weight: bold;
	margin-bottom: 20rpx;
}

.ad-section {
	background-color: #f8f8f8;
	padding: 30rpx;
	border-radius: 10rpx;
	margin-bottom: 30rpx;
}

.ad-desc {
	display: flex;
	flex-direction: column;
	font-size: 28rpx;
	color: #666;
	margin-bottom: 30rpx;
}

.ad-btn {
	background: linear-gradient(to right, #f97632, #ff9466);
	color: #fff;
	border: none;
	border-radius: 10rpx;
	padding: 20rpx;
	font-size: 30rpx;
	width: 100%;
}

.agreement {
	z-index: 99;
	margin-top: 12rpx;
	font-size: 26rpx;
	color: #8f8f8f;
}

.agreement view:nth-child(1) {
	color: black;
	font-weight: 700;
	margin-bottom: 14rpx;
}

.link {
	color: blue;
}
</style>
